package com.example.erp;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.client.transport.ServerParameters;
import io.modelcontextprotocol.client.transport.StdioClientTransport;
import io.modelcontextprotocol.spec.McpSchema;

import java.time.Duration;
import java.util.Map;

/**
 * 采用第三方的mcp服务 @modelcontextprotocol/server-filesystem，基于 mcpclient-java-sdk
 * 实现一个本地智能文件管理服务。
 * <p>
 * 直接访问， main 方法中配置好 server-filesystem 所需参数，不需要其他配置
 * 
 * @author jiang 2025-03-20
 */
public class WithSdkExample {

	private static final String rootDirName = "D:\\share";

	public static void main(String[] args) {
//		本地标准方式 stdio
		ServerParameters params = ServerParameters.builder("D:\\dev\\Nodejs\\npx.cmd")
				.args("-y", "@modelcontextprotocol/server-filesystem", rootDirName).build();
		StdioClientTransport transport = new StdioClientTransport(params, new ObjectMapper());

		// 同步
		try (McpSyncClient client = McpClient.sync(transport)
				.requestTimeout(Duration.ofSeconds(60))
				.clientInfo(new McpSchema.Implementation("jiang-mcp-client", "1.0.0"))
				.capabilities(McpSchema.ClientCapabilities.builder().roots(true).sampling().build()).build()) {
			// 初始化...
			McpSchema.InitializeResult initialize = client.initialize();
			System.out.println("===================client initialized: " + initialize);

			tools(client); // 列出可用的工具列表
//			createDirectory(client); // 创建目录
//			createFile(client); // 创建文件

//			// List available tools
//			ListToolsResult tools = client.listTools();
			//
//			// Call a tool
//			CallToolResult result = client.callTool(new CallToolRequest("calculator", Map.of("operation", "add", "a", 2, "b", 3)));
			//
//			// List and read resources
//			McpSchema.ListResourcesResult resources = client.listResources();
//			// jiang 修改过 20250328
//			McpSchema.ReadResourceResult resource = client.readResource(new McpSchema.Resource("resource://uri", "", "", "", null));
			//
//			// List and use prompts
//			McpSchema.ListPromptsResult prompts = client.listPrompts();
//			McpSchema.GetPromptResult prompt = client.getPrompt(new McpSchema.GetPromptRequest("greeting", Map.of("name", "Spring")));
			//
//			// Add/remove roots
//			client.addRoot(new McpSchema.Root("file:///path", "description"));
//			client.removeRoot("file:///path");
			//
//			// Close client
//			client.closeGracefully();

//			详见：https://modelcontextprotocol.io/sdk/java/mcp-client
//			Using MCP Clients -同步
//			// List available tools and their names
//			var tools = client.listTools();
//			tools.forEach(tool -> System.out.println(tool.getName()));
			//
//			// Execute a tool with parameters
//			var result = client.callTool("calculator", Map.of(
//			    "operation", "add",
//			    "a", 1,
//			    "b", 2
//			));
//			
//			// List available resources and their names
//			var resources = client.listResources();
//			resources.forEach(resource -> System.out.println(resource.getName()));
			//
//			// Retrieve resource content using a URI template
//			var content = client.getResource("file", Map.of(
//			    "path", "/path/to/file.txt"
//			));
//			
//			// List available prompt templates
//			var prompts = client.listPrompts();
//			prompts.forEach(prompt -> System.out.println(prompt.getName()));
			//
//			// Execute a prompt template with parameters
//			var response = client.executePrompt("echo", Map.of(
//			    "text", "Hello, World!"
//			));

//			Using MCP Clients -异步
//			// List available tools asynchronously
//			client.listTools()
//			    .doOnNext(tools -> tools.forEach(tool -> 
//			        System.out.println(tool.getName())))
//			    .subscribe();
			//
//			// Execute a tool asynchronously
//			client.callTool("calculator", Map.of(
//			        "operation", "add",
//			        "a", 1,
//			        "b", 2
//			    ))
//			    .subscribe();
//			
//			// List available resources asynchronously
//			client.listResources()
//			    .doOnNext(resources -> resources.forEach(resource -> 
//			        System.out.println(resource.getName())))
//			    .subscribe();
			//
//			// Retrieve resource content asynchronously
//			client.getResource("file", Map.of(
//			        "path", "/path/to/file.txt"
//			    ))
//			    .subscribe();
//			
//			// List available prompt templates asynchronously
//			client.listPrompts()
//			    .doOnNext(prompts -> prompts.forEach(prompt -> 
//			        System.out.println(prompt.getName())))
//			    .subscribe();
			//
//			// Execute a prompt template asynchronously
//			client.executePrompt("echo", Map.of(
//			        "text", "Hello, World!"
//			    ))
//			    .subscribe();
		}
	}

	/**
	 * 列出可用的工具列表
	 * 
	 * @param client
	 */
	public static void tools(McpSyncClient client) {
		McpSchema.ListToolsResult listToolsResult = client.listTools();
//		listToolsResult.tools().forEach(System.out::println);
		listToolsResult.tools().stream().forEach(tool -> {
			System.err.println("Tool: " + tool.name() + ", description: " + tool.description());
		});
	}

	/**
	 * 创建目录
	 * 
	 * @param client
	 */
	public static void createDirectory(McpSyncClient client) {
		McpSchema.CallToolRequest callToolRequest = new McpSchema.CallToolRequest("create_directory",
				Map.of("path", rootDirName + "\\mcp"));
		McpSchema.CallToolResult callToolResult = client.callTool(callToolRequest);
		System.out.println(callToolResult.content());
	}

	/**
	 * 创建文件
	 * 
	 * @param client
	 */
	public static void createFile(McpSyncClient client) {
		McpSchema.CallToolRequest callToolRequest = new McpSchema.CallToolRequest("write_file",
				Map.of("path", rootDirName + "\\mcp\\test.txt", "content", "hello world"));
		McpSchema.CallToolResult callToolResult = client.callTool(callToolRequest);
		System.out.println(callToolResult.content());
	}

}
